// 广告管理工具类
import { recordAdView, getAdReward, getAdLimit } from '@/api/ads.js'
import antiCheatMonitor from './antiCheatMonitor.js'

// 定义广告平台常量
const AdPlatform = {
  GDT: 'gdt',
  BAIDU: 'baidu',
  BYTEDANCE: 'bytedance',
  KUAISHOU: 'kuaishou'
}

// #ifdef H5
import { AdAdapterFactory } from './h5AdAdapter.js'
// #endif

// #ifndef H5
let AdAdapterFactory = null
// #endif

class AdManager {
  constructor() {
    this.rewardedVideoAd = null
    this.bannerAd = null
    this.interstitialAd = null
    this.isLoading = false
    this.retryCount = 0
    this.maxRetryCount = 3
    
    // 当前平台
    this.platform = this.getPlatform()
    
    // 广告单元ID配置
    this.adUnitIds = {
      // 微信小程序广告位
      miniprogram: {
        rewardedVideo: 'adunit-rewardedvideo',
        banner: 'adunit-banner',
        interstitial: 'adunit-interstitial'
      },
      // H5第三方广告位
      h5: {
        rewardedVideo: 'h5-rewarded-video',
        banner: 'h5-banner',
        interstitial: 'h5-interstitial'
      }
    }
    
    // H5广告相关
    this.h5AdContainer = null
    this.h5AdInstance = null
    this.h5AdAdapter = null
    
    // #ifdef H5
    this.h5AdConfig = {
      platform: process.env.VUE_APP_AD_PLATFORM || AdPlatform.GDT,
      appId: process.env.VUE_APP_AD_APP_ID || 'your-app-id',
      configs: {
        [AdPlatform.GDT]: {
          appId: process.env.VUE_APP_GDT_APP_ID || 'your-gdt-app-id',
          rewardedVideoId: process.env.VUE_APP_GDT_REWARDED_ID || 'your-rewarded-id',
          bannerId: process.env.VUE_APP_GDT_BANNER_ID || 'your-banner-id'
        },
        [AdPlatform.BAIDU]: {
          appId: process.env.VUE_APP_BAIDU_APP_ID || 'your-baidu-app-id',
          rewardedVideoId: process.env.VUE_APP_BAIDU_REWARDED_ID || 'your-rewarded-id',
          bannerId: process.env.VUE_APP_BAIDU_BANNER_ID || 'your-banner-id'
        },
        [AdPlatform.BYTEDANCE]: {
          appId: process.env.VUE_APP_BYTEDANCE_APP_ID || 'your-bytedance-app-id',
          rewardedVideoId: process.env.VUE_APP_BYTEDANCE_REWARDED_ID || 'your-rewarded-id',
          bannerId: process.env.VUE_APP_BYTEDANCE_BANNER_ID || 'your-banner-id'
        }
      }
    }
    // #endif
    
    // #ifndef H5
    this.h5AdConfig = null
    // #endif
    
    this.init()
  }
  
  /**
   * 获取当前平台
   */
  getPlatform() {
    // #ifdef MP-WEIXIN
    return 'miniprogram'
    // #endif
    
    // #ifdef H5
    return 'h5'
    // #endif
    
    return 'unknown'
  }
  
  /**
   * 初始化广告管理器
   */
  init() {
    if (this.platform === 'miniprogram') {
      // #ifdef MP-WEIXIN
      this.initRewardedVideoAd()
      // #endif
    } else if (this.platform === 'h5') {
      // #ifdef H5
      this.initH5Ads()
      // #endif
    }
  }
  
  /**
   * 初始化H5广告
   */
  initH5Ads() {
    // #ifdef H5
    try {
      if (!AdAdapterFactory) {
        console.error('AdAdapterFactory 未加载')
        return
      }
      
      const platform = this.h5AdConfig.platform
      const config = this.h5AdConfig.configs[platform]
      
      if (!config) {
        console.error(`未找到平台 ${platform} 的配置`)
        return
      }
      
      // 创建广告适配器
      this.h5AdAdapter = AdAdapterFactory.createAdapter(platform, config)
      
      // 初始化广告SDK
      this.h5AdAdapter.init().then(() => {
        console.log(`H5广告SDK (${platform}) 初始化成功`)
        this.initH5RewardedVideoAd()
      }).catch((error) => {
        console.error(`H5广告SDK (${platform}) 初始化失败:`, error)
      })
    } catch (error) {
      console.error('初始化H5广告失败:', error)
    }
    // #endif
  }
  
  /**
   * 加载H5广告SDK
   */
  loadH5AdSDK() {
    return new Promise((resolve, reject) => {
      // #ifdef H5
      // 检查是否已经加载
      if (window.GDT && window.GDT.Ad) {
        resolve()
        return
      }
      
      // 创建script标签加载SDK
      const script = document.createElement('script')
      script.src = 'https://qzonestyle.gtimg.cn/qzone/biz/gdt/lib/alloyad/alloyad.js'
      script.async = true
      
      script.onload = () => {
        if (window.GDT && window.GDT.Ad) {
          resolve()
        } else {
          reject(new Error('广告SDK加载失败'))
        }
      }
      
      script.onerror = () => {
        reject(new Error('广告SDK脚本加载失败'))
      }
      
      document.head.appendChild(script)
      // #endif
      
      // #ifndef H5
      reject(new Error('当前环境不支持H5广告'))
      // #endif
    })
  }
  
  /**
   * 初始化H5激励视频广告
   */
  initH5RewardedVideoAd() {
    // #ifdef H5
    try {
      if (!this.h5AdAdapter) {
        console.error('H5广告适配器未初始化')
        return
      }
      
      const platform = this.h5AdConfig.platform
      const config = this.h5AdConfig.configs[platform]
      
      // 创建激励视频广告实例
      this.h5AdInstance = this.h5AdAdapter.createRewardedVideoAd({
        placementId: config.rewardedVideoId
      })
      
      // 监听广告事件
      const adInstance = this.h5AdInstance.instance
      
      if (adInstance.on) {
        adInstance.on('load', () => {
          console.log('H5激励视频广告加载成功')
          this.isLoading = false
          this.retryCount = 0
        })
        
        adInstance.on('error', (error) => {
          console.error('H5激励视频广告错误:', error)
          this.isLoading = false
          this.handleH5AdError(error)
        })
        
        adInstance.on('close', (result) => {
          console.log('H5激励视频广告关闭:', result)
          this.handleH5AdClose(result)
        })
        
        adInstance.on('reward', (reward) => {
          console.log('H5激励视频广告奖励:', reward)
          this.handleH5AdReward(reward)
        })
      }
      
    } catch (error) {
      console.error('初始化H5激励视频广告失败:', error)
    }
    // #endif
  }
  
  /**
   * 初始化激励视频广告
   */
  initRewardedVideoAd() {
    // #ifdef MP-WEIXIN
    if (wx.createRewardedVideoAd) {
      this.rewardedVideoAd = wx.createRewardedVideoAd({
        adUnitId: this.adUnitIds.rewardedVideo
      })
      
      // 监听广告加载成功
      this.rewardedVideoAd.onLoad(() => {
        console.log('激励视频广告加载成功')
        this.isLoading = false
        this.retryCount = 0
      })
      
      // 监听广告加载失败
      this.rewardedVideoAd.onError((err) => {
        console.error('激励视频广告加载失败:', err)
        this.isLoading = false
        this.handleAdError(err)
      })
      
      // 监听广告关闭
      this.rewardedVideoAd.onClose((res) => {
        console.log('激励视频广告关闭:', res)
        this.handleAdClose(res)
      })
    } else {
      console.warn('当前微信版本不支持激励视频广告')
    }
    // #endif
  }
  
  /**
   * 显示激励视频广告
   * @returns {Promise} 广告播放结果
   */
  showRewardedVideoAd() {
    return new Promise((resolve, reject) => {
      // 开始行为监控
      antiCheatMonitor.startMonitoring()
      
      if (this.platform === 'miniprogram') {
        this.showMiniprogramRewardedVideoAd(resolve, reject)
      } else if (this.platform === 'h5') {
        this.showH5RewardedVideoAd(resolve, reject)
      } else {
        reject(new Error('当前环境不支持激励视频广告'))
      }
    })
  }
  
  /**
   * 显示小程序激励视频广告
   */
  showMiniprogramRewardedVideoAd(resolve, reject) {
    // #ifdef MP-WEIXIN
    if (!this.rewardedVideoAd) {
      reject(new Error('激励视频广告未初始化'))
      return
    }
    
    // 设置广告回调
    this.adPromiseResolve = resolve
    this.adPromiseReject = reject
    
    // 记录广告开始时间
    this.adStartTime = Date.now()
    
    // 显示广告
    this.rewardedVideoAd.show().catch((err) => {
      console.error('显示激励视频广告失败:', err)
      
      // 如果是广告未加载，尝试重新加载
      if (err.errCode === 1004) {
        this.loadAndShowRewardedVideoAd()
      } else {
        reject(new Error('广告显示失败: ' + err.errMsg))
      }
    })
    // #endif
  }
  
  /**
   * 显示H5激励视频广告
   */
  showH5RewardedVideoAd(resolve, reject) {
    // #ifdef H5
    if (!this.h5AdInstance) {
      reject(new Error('H5激励视频广告未初始化'))
      return
    }
    
    // 设置广告回调
    this.adPromiseResolve = resolve
    this.adPromiseReject = reject
    
    // 记录广告开始时间
    this.adStartTime = Date.now()
    
    try {
      // 显示H5激励视频广告
      this.h5AdInstance.show()
    } catch (error) {
      console.error('显示H5激励视频广告失败:', error)
      reject(new Error('广告显示失败: ' + error.message))
    }
    // #endif
  }
  
  /**
   * 加载并显示激励视频广告
   */
  loadAndShowRewardedVideoAd() {
    if (this.isLoading || this.retryCount >= this.maxRetryCount) {
      this.adPromiseReject && this.adPromiseReject(new Error('广告加载失败，请稍后重试'))
      return
    }
    
    this.isLoading = true
    this.retryCount++
    
    // #ifdef MP-WEIXIN
    this.rewardedVideoAd.load().then(() => {
      return this.rewardedVideoAd.show()
    }).catch((err) => {
      console.error('重新加载广告失败:', err)
      this.isLoading = false
      
      if (this.retryCount < this.maxRetryCount) {
        setTimeout(() => {
          this.loadAndShowRewardedVideoAd()
        }, 1000)
      } else {
        this.adPromiseReject && this.adPromiseReject(new Error('广告加载失败'))
      }
    })
    // #endif
  }
  
  /**
   * 处理广告关闭事件
   * @param {Object} res - 关闭结果
   */
  async handleAdClose(res) {
    const adEndTime = Date.now()
    const viewDuration = adEndTime - this.adStartTime
    
    // 停止行为监控并分析
    antiCheatMonitor.stopMonitoring()
    const behaviorAnalysis = antiCheatMonitor.analyzeBehavior()
    
    try {
      // 记录广告观看，包含行为分析数据
      const adViewData = {
        adType: 'rewardedVideo',
        adUnitId: this.getCurrentAdUnitId('rewardedVideo'),
        platform: this.platform,
        viewDuration: viewDuration,
        isCompleted: res && res.isEnded,
        timestamp: this.adStartTime,
        behaviorAnalysis: behaviorAnalysis,
        deviceInfo: antiCheatMonitor.getDeviceInfo()
      }
      
      await recordAdView(adViewData)
      
      // 如果用户完整观看了广告
      if (res && res.isEnded) {
        // 检查行为分析结果
        if (behaviorAnalysis.riskScore > 70) {
          console.warn('检测到高风险行为:', behaviorAnalysis.riskFactors)
          this.adPromiseResolve && this.adPromiseResolve({
            success: true,
            completed: false,
            message: '观看行为异常，无法获得奖励'
          })
          return
        }
        
        // 获取广告奖励
        const rewardResult = await getAdReward({
          adType: 'rewardedVideo',
          adUnitId: this.getCurrentAdUnitId('rewardedVideo'),
          platform: this.platform,
          timestamp: this.adStartTime
        })
        
        this.adPromiseResolve && this.adPromiseResolve({
          success: true,
          completed: true,
          reward: rewardResult.data
        })
      } else {
        // 用户中途退出
        this.adPromiseResolve && this.adPromiseResolve({
          success: true,
          completed: false,
          message: '需要完整观看广告才能获得奖励'
        })
      }
    } catch (error) {
      console.error('处理广告奖励失败:', error)
      this.adPromiseReject && this.adPromiseReject(error)
    }
  }
  
  /**
   * 处理H5广告关闭事件
   * @param {Object} result - 关闭结果
   */
  async handleH5AdClose(result) {
    const adEndTime = Date.now()
    const viewDuration = adEndTime - this.adStartTime
    
    try {
      // 记录广告观看
      const adViewData = {
        adType: 'rewardedVideo',
        adUnitId: this.getCurrentAdUnitId('rewardedVideo'),
        platform: 'h5',
        viewDuration: viewDuration,
        isCompleted: result && result.completed,
        timestamp: this.adStartTime
      }
      
      await recordAdView(adViewData)
      
      // 如果用户完整观看了广告
      if (result && result.completed) {
        // 获取广告奖励
        const rewardResult = await getAdReward({
          adType: 'rewardedVideo',
          adUnitId: this.getCurrentAdUnitId('rewardedVideo'),
          platform: 'h5',
          timestamp: this.adStartTime
        })
        
        this.adPromiseResolve && this.adPromiseResolve({
          success: true,
          completed: true,
          reward: rewardResult.data
        })
      } else {
        // 用户中途退出
        this.adPromiseResolve && this.adPromiseResolve({
          success: true,
          completed: false,
          message: '需要完整观看广告才能获得奖励'
        })
      }
    } catch (error) {
      console.error('处理H5广告奖励失败:', error)
      this.adPromiseReject && this.adPromiseReject(error)
    }
  }
  
  /**
   * 处理H5广告奖励事件
   * @param {Object} reward - 奖励信息
   */
  handleH5AdReward(reward) {
    console.log('H5广告奖励:', reward)
    // 奖励处理在关闭事件中统一处理
  }
  
  /**
   * 处理H5广告错误
   * @param {Object} error - 错误信息
   */
  handleH5AdError(error) {
    console.error('H5广告错误:', error)
    
    let errorMessage = '广告加载失败'
    
    if (error.code) {
      switch (error.code) {
        case 1001:
          errorMessage = '广告位配置错误'
          break
        case 1002:
          errorMessage = '网络连接失败'
          break
        case 1003:
          errorMessage = '广告素材加载失败'
          break
        case 1004:
          errorMessage = '暂无合适的广告'
          break
        default:
          errorMessage = error.message || '未知错误'
      }
    }
    
    if (this.adPromiseReject) {
      this.adPromiseReject(new Error(errorMessage))
    }
  }
  
  /**
   * 获取当前平台的广告单元ID
   * @param {string} adType - 广告类型
   * @returns {string} 广告单元ID
   */
  getCurrentAdUnitId(adType) {
    return this.adUnitIds[this.platform] && this.adUnitIds[this.platform][adType] || 'unknown'
  }
  
  /**
   * 处理广告错误
   * @param {Object} err - 错误信息
   */
  handleAdError(err) {
    console.error('广告错误:', err)
    
    let errorMessage = '广告加载失败'
    
    switch (err.errCode) {
      case 1000:
        errorMessage = '后端接口调用失败'
        break
      case 1001:
        errorMessage = '参数错误'
        break
      case 1002:
        errorMessage = '广告单元无效'
        break
      case 1003:
        errorMessage = '内部错误'
        break
      case 1004:
        errorMessage = '无合适的广告'
        break
      case 1005:
        errorMessage = '广告组件审核中'
        break
      case 1006:
        errorMessage = '广告组件被驳回'
        break
      case 1007:
        errorMessage = '广告组件被封禁'
        break
      case 1008:
        errorMessage = '广告单元已关闭'
        break
      default:
        errorMessage = err.errMsg || '未知错误'
    }
    
    if (this.adPromiseReject) {
      this.adPromiseReject(new Error(errorMessage))
    }
  }
  
  /**
   * 创建Banner广告
   * @param {Object} options - 广告配置
   */
  createBannerAd(options = {}) {
    if (this.platform === 'miniprogram') {
      this.createMiniprogramBannerAd(options)
    } else if (this.platform === 'h5') {
      this.createH5BannerAd(options)
    }
  }
  
  /**
   * 创建小程序Banner广告
   */
  createMiniprogramBannerAd(options = {}) {
    // #ifdef MP-WEIXIN
    if (wx.createBannerAd) {
      const systemInfo = uni.getSystemInfoSync()
      
      this.bannerAd = wx.createBannerAd({
        adUnitId: this.getCurrentAdUnitId('banner'),
        adIntervals: 30,
        style: {
          left: 0,
          top: systemInfo.windowHeight - 80,
          width: systemInfo.windowWidth,
          ...options.style
        }
      })
      
      this.bannerAd.onLoad(() => {
        console.log('Banner广告加载成功')
      })
      
      this.bannerAd.onError((err) => {
        console.error('Banner广告加载失败:', err)
      })
      
      this.bannerAd.onResize((res) => {
        console.log('Banner广告尺寸变化:', res)
      })
    }
    // #endif
  }
  
  /**
   * 创建H5 Banner广告
   */
  createH5BannerAd(options = {}) {
    // #ifdef H5
    try {
      if (!this.h5AdAdapter) {
        console.error('H5广告适配器未初始化')
        return
      }
      
      // 创建Banner广告容器
      const containerId = options.containerId || 'h5-banner-ad-container'
      let container = document.getElementById(containerId)
      
      if (!container) {
        container = document.createElement('div')
        container.id = containerId
        container.style.cssText = `
          position: fixed;
          bottom: 0;
          left: 0;
          right: 0;
          height: 80px;
          z-index: 9999;
          background: #f5f5f5;
          display: flex;
          align-items: center;
          justify-content: center;
        `
        document.body.appendChild(container)
      }
      
      this.h5AdContainer = container
      
      const platform = this.h5AdConfig.platform
      const config = this.h5AdConfig.configs[platform]
      
      // 创建Banner广告实例
      this.bannerAd = this.h5AdAdapter.createBannerAd({
        placementId: config.bannerId,
        container: container,
        width: options.width || 320,
        height: options.height || 50
      })
      
      // 监听Banner广告事件
      const adInstance = this.bannerAd.instance
      
      if (adInstance.on) {
        adInstance.on('load', () => {
          console.log('H5 Banner广告加载成功')
        })
        
        adInstance.on('error', (error) => {
          console.error('H5 Banner广告加载失败:', error)
        })
        
        adInstance.on('click', () => {
          console.log('H5 Banner广告被点击')
          this.recordH5BannerClick()
        })
      }
      
    } catch (error) {
      console.error('创建H5 Banner广告失败:', error)
    }
    // #endif
  }
  
  /**
   * 记录H5 Banner广告点击
   */
  async recordH5BannerClick() {
    try {
      await recordAdView({
        adType: 'banner',
        adUnitId: this.getCurrentAdUnitId('banner'),
        platform: 'h5',
        viewDuration: 0,
        isCompleted: true,
        timestamp: Date.now()
      })
    } catch (error) {
      console.error('记录Banner广告点击失败:', error)
    }
  }
  
  /**
   * 显示Banner广告
   */
  showBannerAd() {
    if (this.platform === 'miniprogram') {
      // #ifdef MP-WEIXIN
      if (this.bannerAd) {
        this.bannerAd.show()
      }
      // #endif
    } else if (this.platform === 'h5') {
      // #ifdef H5
      if (this.h5AdContainer) {
        this.h5AdContainer.style.display = 'flex'
      }
      if (this.bannerAd && this.bannerAd.show) {
        this.bannerAd.show()
      }
      // #endif
    }
  }
  
  /**
   * 隐藏Banner广告
   */
  hideBannerAd() {
    if (this.platform === 'miniprogram') {
      // #ifdef MP-WEIXIN
      if (this.bannerAd) {
        this.bannerAd.hide()
      }
      // #endif
    } else if (this.platform === 'h5') {
      // #ifdef H5
      if (this.h5AdContainer) {
        this.h5AdContainer.style.display = 'none'
      }
      if (this.bannerAd && this.bannerAd.hide) {
        this.bannerAd.hide()
      }
      // #endif
    }
  }
  
  /**
   * 销毁Banner广告
   */
  destroyBannerAd() {
    if (this.platform === 'miniprogram') {
      // #ifdef MP-WEIXIN
      if (this.bannerAd) {
        this.bannerAd.destroy()
        this.bannerAd = null
      }
      // #endif
    } else if (this.platform === 'h5') {
      // #ifdef H5
      if (this.bannerAd && this.bannerAd.destroy) {
        this.bannerAd.destroy()
        this.bannerAd = null
      }
      if (this.h5AdContainer && this.h5AdContainer.parentNode) {
        this.h5AdContainer.parentNode.removeChild(this.h5AdContainer)
        this.h5AdContainer = null
      }
      // #endif
    }
  }
  
  /**
   * 获取今日观看限制
   * @returns {Promise} 限制信息
   */
  async getTodayAdLimit() {
    try {
      const result = await getAdLimit()
      return result.data
    } catch (error) {
      console.error('获取广告限制失败:', error)
      throw error
    }
  }
  
  /**
   * 检查是否可以观看广告
   * @returns {Promise<boolean>} 是否可以观看
   */
  async canWatchAd() {
    try {
      const limitInfo = await this.getTodayAdLimit()
      return limitInfo.canWatch
    } catch (error) {
      console.error('检查广告限制失败:', error)
      return false
    }
  }
  
  /**
   * 销毁所有广告
   */
  destroy() {
    if (this.platform === 'miniprogram') {
      // #ifdef MP-WEIXIN
      if (this.rewardedVideoAd) {
        this.rewardedVideoAd.destroy()
        this.rewardedVideoAd = null
      }
      
      if (this.interstitialAd) {
        this.interstitialAd.destroy()
        this.interstitialAd = null
      }
      // #endif
    } else if (this.platform === 'h5') {
      // #ifdef H5
      if (this.h5AdInstance && this.h5AdInstance.destroy) {
        this.h5AdInstance.destroy()
        this.h5AdInstance = null
      }
      // #endif
    }
    
    this.destroyBannerAd()
  }
}

// 创建单例实例
const adManager = new AdManager()

export default adManager
export { AdPlatform }